package com.sneaker.shower.controller;

import com.sneaker.shower.common.BizException;
import com.sneaker.shower.common.ThreadLocalCache;
import com.sneaker.shower.entity.domain.organization.OrganizationDO;
import com.sneaker.shower.entity.domain.sys.SysUserDO;
import com.sneaker.shower.entity.domain.user.UserDO;
import com.sneaker.shower.entity.dto.UserDTO;
import com.sneaker.shower.mapstruct.SysUserMapStruct;
import com.sneaker.shower.mapstruct.UserMapStruct;
import com.sneaker.shower.service.OrganizationService;
import com.sneaker.shower.service.SysUserService;
import com.sneaker.shower.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.Base64Utils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;

@Configuration
@Slf4j
public class UserInterceptor implements HandlerInterceptor {
    private final static String[] whiteList = {
            "/user/login", "/user/info",
            "/sysUser/invitationCode",
            "/sysUser/addSysUser",
            "/sysUser/login/",
            "/organization/addOrganization",
            "/organization/delOrganization",
            "/organization/modifyOrganization",
            "/organization/OrganizationDTO",
            "/organization/currentOrganization",
            "/sysUser/addSysUser",
            "/file/download",
            "/file/upload",
            "/wx_mp",
            "/wx_ma",
            "/wx_pay/callBack",
            "/coupon",
            "/user/charge_status",
            "/wx/download_bill",
            "/organization/upload_main_images",
            "/organization/get_main_images",
            //TODO swagger相关 上线后去掉
            "/sysUser/delSysUser",//TODO 删除客服，上线后取消这个白名单
            "/swagger-ui.html",
            "/error",
            "/swagger-resources",
            "/v2/api-docs",
            "/webjars/",
            "/configuration/",
            "/ws",
            "/kefu/callback",
            "/sub_order/kuaidi",
            "/images/",
            "/kefu/channels",
            "/kefu/groups",
            "/sysUser/invitationCode"
    };
    private final static List<String> WHITE_LIST = Arrays.asList(whiteList);
    private static final String MENU_REQ_URI = "/menu/";
    private static final String ORG_CHECK = "/organization/check_status";
    @Autowired
    UserService userService;
    @Autowired
    SysUserService sysUserService;
    @Autowired
    OrganizationService organizationService;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String uri = request.getRequestURI();
        if (WHITE_LIST.stream().anyMatch(uri::startsWith)) {
            return true;
        }
        String userInfo = request.getHeader("USER_INFO");
        String userType = request.getHeader("USER_TYPE");
        String orgGuidStr = request.getHeader("ORG_GUID");
        log.info("当前请求：用户信息:【{}】, 用户类型:【{}】, 门店:【{}】", userInfo, userType, orgGuidStr);
        if (StringUtils.isEmpty(orgGuidStr)) {
            throw new BizException("未获取到门店信息");
        }
        Long orgGuid = Long.valueOf(orgGuidStr);
        OrganizationDO organizationDO = organizationService.getById(orgGuid);
        if (ObjectUtils.isEmpty(organizationDO)) {
            throw new BizException("未获取到门店信息");
        }
        if (uri.startsWith(MENU_REQ_URI) || uri.startsWith(ORG_CHECK)) {
            UserDTO userDTO = new UserDTO();
            userDTO.setOrganizationGuid(String.valueOf(orgGuid));
            saveToCache(userDTO, organizationDO);
            return true;
        }

        if (!StringUtils.isBlank(userInfo) && !StringUtils.isBlank(userType)) {
            if (StringUtils.equals(userType, "user")) {
                UserDO userDO = userService.getById(userInfo);
                if (userDO == null) {
                    throw new BizException("该功能需要登录后才能使用哟");
                }
                UserDTO userDTO = UserMapStruct.INSTANCE.do2DTO(userDO, userType);
                userDTO.setOrganizationGuid(String.valueOf(orgGuid));
                userDTO.setNickName(new String(Base64Utils.decodeFromString(userDTO.getNickName())));
                userDTO.setRemarkName(new String(Base64Utils.decodeFromString(userDTO.getRemarkName())));
                userDTO.setUserVersion(userDO.getVersion());
                saveToCache(userDTO, organizationDO);
            } else {
                SysUserDO user = sysUserService.getById(userInfo);
                if (user == null) {
                    throw new BizException("该功能需要登录后才能使用哟");
                }
                UserDTO userDTO = SysUserMapStruct.INSTANCE.do2DTO(user, userType);
                userDTO.setOrganizationGuid(String.valueOf(orgGuid));
                saveToCache(userDTO, organizationDO);
            }
        } else {
            throw new BizException("该功能需要登录后才能使用哟");
        }
        return true;
    }

    private void saveToCache(UserDTO userDTO, OrganizationDO org) {
        ThreadLocalCache.set(userDTO);
        ThreadLocalCache.setOrgThreadLocal(org);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        ThreadLocalCache.set(null);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

    }

}
